package com.github.controller;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.bean.*;
import com.github.config.ZEGOConfig;
import com.github.constant.MyConstant;
import com.github.manager.Manager;
import com.github.pojo.Result;
import com.github.service.UserServer;
import com.github.util.Role;
import com.github.util.Utils;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Iterator;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class VastController {
    // 在控制器或服务中添加测试
    private final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Autowired
    private UserServer userServer;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedissonClient redissonClient;

    @PostMapping("/api/get_setting")
    public Result<?> getSetting(@RequestBody Device device) {
        Setting setting = new Setting();
        setting.setZe_go_app_id(ZEGOConfig.appID);
        setting.setZe_go_app_sign(ZEGOConfig.appSign);
        return Result.success(setting);
    }

    @PostMapping("/api/server_login")
    public Result<?> serverLogin(@RequestBody User user) {
        RLock lock = redissonClient.getLock(MyConstant.Login_Lock+user.getAccount());
        try {
            boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (!locked) {
                log.error("获取锁失败 用户操作频繁 | account={}", user.getAccount());
                return Result.error("系统繁忙，请稍后重试");
            }
            Object userObj = stringRedisTemplate.opsForHash().get(MyConstant.UserInfoCache, user.getAccount());
            if (userObj == null) {
                log.info("用户不存在，进行拦截处理 | account={}", user.getAccount());
                return Result.error("用户不存在或密码错误");
            }
            User userCache = JSONUtil.toBean(userObj.toString(), User.class);
            if (!userCache.getPassword().equals(user.getPassword())) {
                log.info("用户密码错误，进行拦截处理 | account={}", user.getAccount());
                return Result.error("用户不存在或密码错误");
            }
            Object oldTokenJson = stringRedisTemplate.opsForHash().get(MyConstant.UserLoginAccount, user.getAccount());
            if (null!= oldTokenJson && getIsServerOnline(user.getAccount())) {
                log.info("用户已经在其他设备登录 | account={}", user.getAccount());
                return Result.error("用户已经在其他设备登录");
            }
            // 保证一个valueAccount只对应一个tokenKey
            if (oldTokenJson!=null) {
                String oldToken=oldTokenJson.toString();
                stringRedisTemplate.opsForHash().delete(MyConstant.UserLoginToken , oldToken);
                stringRedisTemplate.opsForHash().delete(MyConstant.UserLoginAccount , user.getAccount());
            }

            String token = Utils.getToken();
            stringRedisTemplate.opsForHash().put(MyConstant.UserLoginToken , token, user.getAccount());
            stringRedisTemplate.opsForHash().put(MyConstant.UserLoginAccount , user.getAccount(), token);
            log.info("登录成功 | account={} | token={}", user.getAccount(), token);
            Login login = new Login();
            login.setTicket(user.getAccount());
            login.setToken(token);
            return Result.success(login);
        } catch (InterruptedException e) {
            return Result.error("操作频繁");
        } finally {
            lock.unlock();
        }
    }

    public boolean getIsServerOnline(String account) {
        ServerUser serverUser = Manager.accountUserMap.getOrDefault(account, null);
        if (serverUser == null)
            return false;
        return serverUser.isServerOnline();
    }

    @PostMapping("/api/server_logout")
    public Result<?> serverLogout(@RequestBody String str) {
        JsonNode jsonNode = Utils.toJsonNode(str);
        String token = null;
        if (jsonNode != null) {
            token = jsonNode.path("token").asText();
        }
        Object accountJson = stringRedisTemplate.opsForHash().get(MyConstant.UserLoginToken, token);

        if (accountJson == null){
            log.info("用户退出登录 account为空  | token={}",  token);
            return Result.success(null);
        }

        String account = accountJson.toString();
        stringRedisTemplate.opsForHash().delete(MyConstant.UserLoginToken , token);
        stringRedisTemplate.opsForHash().delete(MyConstant.UserLoginAccount , account);
        userServer.logout(account);
        log.info("用户退出登录成功 | account={} | token={}", account, token);

        return Result.success(null);
    }
}
